from scipy import *
from numpy import power

class Cbid:
    def __init__(self, p, s):
        self.p = p
        self.s = s
        self.r = p * s
    
    def __repr__(self):
        return '''(p:%f, s:%f, r:%f)''' % (self.p, self.s, self.r)
        
def bids_key(bid):
    return bid.r

def getPt(i, bids):
    '''
 
               /Put(i+1), if Put(i) > Put(i+1)    
        pt(i) =
               \Put(i+1)*Sut(i+1)/Sut(i)
         
    '''
    pt = 0.0
    length = len(bids)
    
    if((length-1) == i):    #the tail
        pt = (bids[i]).p
    else:
        if((bids[i]).p >= (bids[i+1]).p):
            pt = (bids[i+1]).p
        else:
            pt = (bids[i+1]).r / (bids[i]).s
    return pt
    
def getRevenue(i, bids, tao):
    '''
        Rexp(i) = pt(i) * St(i) / (tao^i)
        i starts from 0
    '''
    length = len(bids)
    if i < length:
        p = getPt(i, bids)
        return p*(bids[i].s)/(power(tao, i))
    else:
        return 0.0

def getStepRevenue(bids, k, tao):
    '''
        for one single poisson arrival step, get the
        total value of k ad slots
        tao: the decaying click factor of slot order
    '''
    sum = 0.0
    for i in xrange(0, k):
        sum = sum + getRevenue(i, bids, tao)
    return sum

def sgn(x):
    '''       / x/|x|, x!=0
        sgn(x)= 
              \ -1, x=0
    '''
    if x > 0:
        return 1
    else:
        return -1 

def getY(y0, i, k):
    return power(y0, (k-i))
        
def getOptRevenue(i, k, bids, tao, r0, y0):
    '''
    '''
    length = len(bids)
    if i < length:
        x1 = getRevenue(i, bids, tao=1)
        x2 = getRevenue(i+1, bids, tao=1)
        if 0.0 == x2:
            return x1
        else:
            y = getY(y0, i+1, k)
            return ((sgn(x1-r0)+1)/2)*x2 - ((sgn(r0-x1)+1)/2)*y
    else:
        return 0.0
        
def getStepOptRevenue(bids, k, tao, r0, y0, C):
    '''
    '''
    sum = 0
    for i in xrange(0, k):
        sum = sum + getOptRevenue(i, k, bids, tao, r0, y0)
        
    return sum - (C/r0)